#pragma once

#include <QObject>
#include <QIcon>
#include <QKeySequence>

class QAction;
class QGraphicsSceneMouseEvent;

namespace SymbolEditor
{

    class GraphicsItem;
    class Scene;
    class View;

    typedef QMap<GraphicsItem*, QList<QPointF> > SnapCandidates;

    struct SnapResult
    {
        QPointF pos;
        qreal distance = 0.0;
        GraphicsItem *item = nullptr;
        QString text;
        // QList<QGraphicsItem> decorations;
        inline bool isValid() { return qIsFinite(distance); }
    };

    class AbstractSnapStrategy: public QObject
    {
        Q_OBJECT

    public:
        explicit AbstractSnapStrategy(QObject *parent = nullptr);
        virtual ~AbstractSnapStrategy();

        QAction *action() const;

        void setScene(Scene *scene);
        Scene *scene() const;

        void setView(View *view);
        View *view() const;

        virtual SnapResult snap(QPointF mousePos, qreal maxDistance) = 0;

    protected:
        void setName(const QString &name);
        void setLabel(const QString &label);
        void setShortcut(const QKeySequence &shortcut);
        void setIcon(const QIcon &icon);
        void updateAction();

        QList<GraphicsItem *> items(const QPointF &mousePos, qreal maxDistance);
        SnapResult snap(const QPointF &mousePos, const SnapCandidates &candidates);

    private:
        QAction *m_action = nullptr;
        QString m_label;
        QString m_name;
        QIcon m_icon;
        QKeySequence m_shortcut;
        Scene *m_scene = nullptr;
        View *m_view = nullptr;
    };

}
